package com.cjack.frenchexcel.service;

import com.alibaba.fastjson.JSONObject;
import com.cjack.frenchexcel.config.ErrorCodeDefine;
import com.cjack.frenchexcel.config.LayPage;
import com.cjack.frenchexcel.config.PrivateConfig;
import com.cjack.frenchexcel.dao.ConsumerRecordDao;
import com.cjack.frenchexcel.dao.GoodsDao;
import com.cjack.frenchexcel.dao.SendGoodsRecordDao;
import com.cjack.frenchexcel.dao.UserAdminDao;
import com.cjack.frenchexcel.enumInfo.InvoiceReviewStatusEnum;
import com.cjack.frenchexcel.exception.CommonException;
import com.cjack.frenchexcel.model.SendGoodsRecordExportModel;
import com.cjack.frenchexcel.model.SendGoodsRecordModel;
import com.cjack.frenchexcel.table.AdminUserTable;
import com.cjack.frenchexcel.table.ConsumerRecordTable;
import com.cjack.frenchexcel.table.GoodsTable;
import com.cjack.frenchexcel.table.SendGoodsRecordTable;
import com.cjack.frenchexcel.util.CustomerStringUtil;
import com.cjack.frenchexcel.util.DateFormatUtil;
import com.cjack.frenchexcel.util.FileUtils;
import com.cjack.frenchexcel.util.ModelUtils;
import com.sargeraswang.util.ExcelUtil.ExcelUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.zeroturnaround.zip.ZipUtil;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by root on 10/5/19
 */
@Service
public class SendGoodsRecordService {
    @Value("${file.upload.baseServerDir}")
    String baseServerDir;
    @Value("${file.upload.baseClientDir}")
    String baseClientDir;
    @Value("${file.upload.spelitor}")
    String spelitor;

    @Autowired
    private UserAdminDao userAdminDao;
    @Autowired
    private SendGoodsRecordDao dao;
    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private WordPdfCreateService wordPdfCreateService;
    @Autowired
    private UserAdminService userAdminService;
    @Autowired
    private ConsumerRecordDao consumerRecordDao;

    public Page<SendGoodsRecordTable> list(LayPage page, SendGoodsRecordModel model) {
        Specification<SendGoodsRecordTable> specification = handleConditon(model);
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = new PageRequest(page.getPage() - 1, page.getLimit(), sort);
        Page<SendGoodsRecordTable> resultPage = dao.findAll(specification, pageable);
        return resultPage;
    }

    //商品发货
    public void sendGoods(SendGoodsRecordModel model) {
        //设置商品发货之后的状态
        List<GoodsTable> tables = new ArrayList<>();
        String orderNo = CustomerStringUtil.randomStr(16);
        //创建一条发货记录
        SendGoodsRecordTable sendGoodsRecordTable = new SendGoodsRecordTable();
        sendGoodsRecordTable.setOrderNo(orderNo);
        sendGoodsRecordTable.setSendGoodsNoProfix(CustomerStringUtil.sendGoodsNoProfix());
        sendGoodsRecordTable.setSendGoodsNoNumber(dao.countBySendGoodsNoProfix(sendGoodsRecordTable.getSendGoodsNoProfix()) + 1);
        sendGoodsRecordTable.setCompleteSendGoodsNoNumber(sendGoodsRecordTable.getSendGoodsNoProfix() + CustomerStringUtil.sendGoodsNumber(sendGoodsRecordTable.getSendGoodsNoNumber()));
        sendGoodsRecordTable.setTotalAmount(model.getTotalAmount());
        sendGoodsRecordTable.setCreateTime(new Date());
        sendGoodsRecordTable.setAdminUserId(model.getAdminUserId());
        sendGoodsRecordTable.setGoodsIds(model.getGoodsIds());

        dao.save(sendGoodsRecordTable);
        String[] idArr = model.getGoodsIds().split(",");
        for (String id : idArr) {
            GoodsTable table = goodsDao.getOne(Long.valueOf(id));
            table.setStoreCount(0);
            table.setStatus("2");
            table.setSendGoodsRecordId(sendGoodsRecordTable.getId());
            tables.add(table);
            ConsumerRecordTable consumerRecordTable = consumerRecordDao.getOne(table.getConsumerRecordId());
            consumerRecordTable.setNoFacture(sendGoodsRecordTable.getCompleteSendGoodsNoNumber());
            consumerRecordDao.save(consumerRecordTable);
        }
        goodsDao.save(tables);
        //计算商品销售总价格，注意保存这里的顺序
        BigDecimal totalBg = new BigDecimal(0);
        for (GoodsTable good : tables) {
            totalBg = totalBg.add(new BigDecimal(good.getSellPrice()));
        }
        sendGoodsRecordTable.setTotalSellAmount(totalBg.doubleValue());
        dao.save(sendGoodsRecordTable);

        //生成商品销售的发票-发票这里跟客户商议，直接保存word文件即可，不需要转pdf或者转图片
        String wordFile = wordPdfCreateService.createSendGoodsInvoice(tables, sendGoodsRecordTable);
        sendGoodsRecordTable.setSellInvoicePdf(wordFile);
        sendGoodsRecordTable.setSellInvoiceImg(null);
        dao.save(sendGoodsRecordTable);
    }

    public JSONObject exportAsExcel(SendGoodsRecordModel condition) throws CommonException {
        Specification<SendGoodsRecordTable> specification = handleConditon(condition);
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        List<SendGoodsRecordTable> datas = dao.findAll(specification, sort);
        String fileType = "sendGoodsRecordExportExcel";
        //先创建excel空文件
        String fileName = FileUtils.getXlsxFileName();
        String dumic = fileType + spelitor + FileUtils.getDirByDate();//动态的这一截路径
        //服务器保存文件的目录
        String destDir = baseServerDir + dumic;
        //供浏览器客户端访问的目录
        String clientDir = baseClientDir + dumic;
        //处理目录不存在则创建
        FileUtils.handleDir(destDir);
        File dest = new File(destDir + spelitor + fileName);
        //需要导出的数据
        List<SendGoodsRecordExportModel> exportDatas = build(datas);
        //导出的列 title信息
        Map<String, String> col = SendGoodsRecordExportModel.getColMap();
        OutputStream out;
        try {
            out = new FileOutputStream(dest);
            ExcelUtil.exportExcel(col, exportDatas, out);
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new CommonException(ErrorCodeDefine.INTERFACE_COMMON_ERROR, "导出excel失败");
        } catch (IOException e) {
            e.printStackTrace();
            throw new CommonException(ErrorCodeDefine.INTERFACE_COMMON_ERROR, "导出excel失败");
        }

        //将导出成功的excel地址和导出数据的条数返回给客户端
        JSONObject json = new JSONObject();
        json.put("exportCount", exportDatas.size());
        json.put("filePath", clientDir + spelitor + fileName);
        return json;
    }

    public JSONObject exportInvoice(SendGoodsRecordModel condition) throws Exception {
        //需要导出的数据
        Specification<SendGoodsRecordTable> specification = handleConditon(condition);
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        List<SendGoodsRecordTable> datas = dao.findAll(specification, sort);
        String fileType = "sendGoodsRecordExportZip";
        //先创建excel空文件
        String fileName = FileUtils.getZipFileName();
        String dumic = fileType + spelitor + FileUtils.getDirByDate();//动态的这一截路径
        //服务器保存文件的目录
        String destDir = baseServerDir + dumic;
        //供浏览器客户端访问的目录
        String clientDir = baseClientDir + dumic;
        //处理目录不存在则创建
        FileUtils.handleDir(destDir);
        String finalPdfPath = destDir + spelitor + FileUtils.getPdfFileName();
        String zipPath = destDir + spelitor + fileName;

        File[] pdfFilePaths = new File[datas.size()];
        for (int i = 0; i < datas.size(); i++) {
            SendGoodsRecordTable exportData = datas.get(i);
            String pdfFilePath = FileUtils.transferClientFileUrl(exportData.getSellInvoicePdf(), baseClientDir,
                    baseServerDir);
            pdfFilePaths[i] = new File(pdfFilePath);
        }
        ZipUtil.packEntries(pdfFilePaths, new File(zipPath));

        //将导出成功的excel地址和导出数据的条数返回给客户端
        JSONObject json = new JSONObject();
        json.put("exportCount", datas.size());
        json.put("filePath", clientDir + spelitor + fileName);
        return json;
    }

    private List<SendGoodsRecordExportModel> build(List<SendGoodsRecordTable> datas) {
        DecimalFormat df = new DecimalFormat("#.00");
        List<SendGoodsRecordExportModel> models = new ArrayList<>();
        for (SendGoodsRecordTable data : datas) {
            SendGoodsRecordExportModel model = new SendGoodsRecordExportModel();
            model.setCompleteSendGoodsNoNumber(data.getCompleteSendGoodsNoNumber());
            model.setCreateTime(DateFormatUtil.format(data.getCreateTime(), DateFormatUtil.DATE_RULE_3));
            model.setTotalSellAmount(df.format(data.getTotalSellAmount()));
            models.add(model);
        }
        return models;
    }

    public SendGoodsRecordTable get(Long id) {
        return dao.getOne(id);
    }

    public void save(SendGoodsRecordModel model) {
        SendGoodsRecordTable table;
        if (model.getId() != null && !model.getId().equals(0l)) {
            table = dao.getOne(model.getId());
        } else {
            table = new SendGoodsRecordTable();
        }
        ModelUtils.copySignModel(model, table);
        //根据传过来的参数判断 是否是上传出关单，如果是的话，需要根据发货的金额计算员工本次增加的积分
        if (StringUtils.isNotEmpty(model.getTrackingNumber()) && StringUtils.isNotEmpty(model.getCustomsClearanceFormImg())) {
            userAdminService.handleMoneyToIntegral(table.getAdminUserId(), model.getTotalAmount());
            //设置上传出关单时间
            table.setUploadCustomsClearanceFormTime(new Date());
        }
        //出关单审核通过，修改对应商品状态
        if (StringUtils.equals(InvoiceReviewStatusEnum.PASS.getCode(), table.getReviewStatus())) {
            String[] idArr = table.getGoodsIds().split(",");
            for (String id : idArr) {
                GoodsTable goodsTable = goodsDao.getOne(Long.valueOf(id));
                goodsTable.setStatus("3");
                goodsDao.save(goodsTable);
            }
        }
        dao.save(table);
    }

    /**
     * 组装查询条件
     *
     * @return
     */
    private Specification<SendGoodsRecordTable> handleConditon(SendGoodsRecordModel model) {
        Specification<SendGoodsRecordTable> specification = new Specification<SendGoodsRecordTable>() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
                Predicate predicate = cb.conjunction();
                //判断权限，判断是否有查询所有数据的权限
                AdminUserTable adminUserTable = userAdminDao.findOne(model.getAdminUserId());
                String roleContent = adminUserTable.getRole().getContent();
                if (!PrivateConfig.checkPrivalege(roleContent, PrivateConfig.GOODS_LIST_ALL)) {
                    predicate.getExpressions().add(cb.equal(root.get("adminUserId").as(Long.class),
                            model.getAdminUserId()));
                }
                if (StringUtils.isNotEmpty(model.getCompleteSendGoodsNoNumber())) {
                    predicate.getExpressions().add(cb.like(root.get("completeSendGoodsNoNumber").as(String.class),
                            "%" + model.getCompleteSendGoodsNoNumber() + "%"));
                }
                return predicate;
            }
        };
        return specification;
    }
}
